//****************************************************
// Porman Project 2
// Filename: CGLDef.h
// Date: 2007/10/06
// Author: KengYu Lin
// Modify:
//****************************************************
#ifndef _CGLDEF_H
#define _CGLDEF_H

#include <iostream>
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#include <string>

#include "GLee/GLee.h"
#include <gl/glu.h>
#include "Cg/cg.h"
#include "Cg/cgGL.h"

//--------------------------------------------
// Preprocessor definition:
// Date: 07/11/04
// Author: KengYu Lin
// Modify:
//
//--------------------------------------------
#ifdef WIN32
    #include <windows.h>
    #ifdef PGL_EXPORT
        #define PGL_API __declspec(dllexport)
    #else
        #define PGL_API __declspec(dllimport)
    #endif
#else
    #define PGL_API
#endif

#define SAFEDELETE(x) delete x; x = NULL
#define SAFEDELETE_ARRAY(x) delete[]x; x = NULL
#define VE_END()
#define THREAD_CHECKING(x, res) if(x != GetCurrentThreadId()) {assert(0); return res;}
#define THREAD_CHECKING_REF(x, res) if(x != GetCurrentThreadId()) {assert(0); if(res) (*res) = E_THREAD_ERROR; }

namespace Porman
{

namespace GL
{

enum ERESULT
{
    E_SUCCESS,
    E_INVALID_BUFFEROBJ,
    E_INVALID_TYPE,
    E_INVALID_SHADEROBJ,
    E_INVALID_FXOBJ,
    E_INVALID_TEXTUREOBJ,
    E_INVALID_DEPTHSTENCILOBJ,
    E_INVALID_FRAMEBUFFEROBJ,
    E_INVALID_QUERYOBJ,
    E_INVALID_PARAMETER,
    E_INVALID_SHADER_PROFILE,
    E_INVALID_VALUE,
    E_INVALID_OPERATION,
    E_GET_DC_FAIL,
    E_CREATE_PIXELFORMAT_FAIL,
    E_CREATE_FRAMEBUFFER_FAIL,
    E_OUT_OF_MEMORY,
    E_COMPILE_ERROR,
    E_NOT_ENOUGH_DATA,
    E_NON_NUMERIC_PARAMETER,
    E_PARAMETER_IS_NOT_SHARED,
    E_BIND_CREATES_CYCLE,
    E_PARAMETERS_DO_NOT_MATCH,
    E_ARRAY_TYPES_DO_NOT_MATCH,
    E_ARRAY_DIMENSIONS_DO_NOT_MATCH,
    E_FILE_READ_ERROR,
    E_WINDOW_ALREADY_EXIST_PIXELFORMAT,
    E_INITIAL_CG_FAIL,
    E_INITIAL_WORDSYS_FAIL,
    E_OGL_VERSION_NOT_SUPPORT,
    E_THREAD_ERROR,
    E_NONCOMPILE_SHADEROBJ
};

enum IMG_RESULT
{
    IMG_OK              = 0x1,
    IMG_ERR_NO_FILE     = 0x2,
    IMG_ERR_MEM_FAIL    = 0x4,
    IMG_ERR_BAD_FORMAT  = 0x8,
    IMG_ERR_UNSUPPORTED = 0x40
};

enum EDrawSurfaceOptions
{
    E_NUMBER_PIXEL_FORMATS    = WGL_NUMBER_PIXEL_FORMATS_ARB,
    E_DRAW_TO_WINDOW          = WGL_DRAW_TO_WINDOW_ARB,
    E_DRAW_TO_BITMAP          = WGL_DRAW_TO_BITMAP_ARB,                            
    E_ACCELERATION            = WGL_ACCELERATION_ARB,                          
    E_NEED_PALETTE            = WGL_NEED_PALETTE_ARB,                              
    E_NEED_SYSTEM_PALETTE     = WGL_NEED_SYSTEM_PALETTE_ARB,
    E_SWAP_LAYER_BUFFERS      = WGL_SWAP_LAYER_BUFFERS_ARB,                         
    E_SWAP_METHOD             = WGL_SWAP_METHOD_ARB,                                
    E_NUMBER_OVERLAYS         = WGL_NUMBER_OVERLAYS_ARB, 
    E_NUMBER_UNDERLAYS        = WGL_NUMBER_UNDERLAYS_ARB,                           
    E_TRANSPARENT             = WGL_TRANSPARENT_ARB,                                
    E_TRANSPARENT_RED_VALUE   = WGL_TRANSPARENT_RED_VALUE_ARB,
    E_TRANSPARENT_GREEN_VALUE = WGL_TRANSPARENT_GREEN_VALUE_ARB,
    E_TRANSPARENT_BLUE_VALUE  = WGL_TRANSPARENT_BLUE_VALUE_ARB,
    E_TRANSPARENT_ALPHA_VALUE = WGL_TRANSPARENT_ALPHA_VALUE_ARB,                    
    E_TRANSPARENT_INDEX_VALUE = WGL_TRANSPARENT_INDEX_VALUE_ARB,                    
    E_SHARE_DEPTH             = WGL_SHARE_DEPTH_ARB,
    E_SHARE_STENCIL           = WGL_SHARE_STENCIL_ARB,
    E_SHARE_ACCUM             = WGL_SHARE_ACCUM_ARB,                                
    E_SUPPORT_GDI             = WGL_SUPPORT_GDI_ARB,
    E_SUPPORT_OPENGL          = WGL_SUPPORT_OPENGL_ARB,                             
    E_DOUBLE_BUFFER           = WGL_DOUBLE_BUFFER_ARB,
    E_STEREO                  = WGL_STEREO_ARB,
    E_PIXEL_TYPE              = WGL_PIXEL_TYPE_ARB,
    E_COLOR_BITS              = WGL_COLOR_BITS_ARB,                 
    E_RED_BITS                = WGL_RED_BITS_ARB,
    E_RED_SHIFT               = WGL_RED_SHIFT_ARB,
    E_GREEN_BITS              = WGL_GREEN_BITS_ARB,
    E_GREEN_SHIFT             = WGL_GREEN_SHIFT_ARB,
    E_BLUE_BITS               = WGL_BLUE_BITS_ARB,
    E_BLUE_SHIFT              = WGL_BLUE_SHIFT_ARB,
    E_ALPHA_BITS              = WGL_ALPHA_BITS_ARB,                                 
    E_ALPHA_SHIFT             = WGL_ALPHA_SHIFT_ARB,                                
    E_ACCUM_BITS              = WGL_ACCUM_BITS_ARB,
    E_ACCUM_RED_BITS          = WGL_ACCUM_RED_BITS_ARB,
    E_ACCUM_GREEN_BITS        = WGL_ACCUM_GREEN_BITS_ARB,
    E_ACCUM_BLUE_BITS         = WGL_ACCUM_BLUE_BITS_ARB,                            
    E_ACCUM_ALPHA_BITS        = WGL_ACCUM_ALPHA_BITS_ARB,                           
    E_DEPTH_BITS              = WGL_DEPTH_BITS_ARB,
    E_STENCIL_BITS            = WGL_STENCIL_BITS_ARB,
    E_AUX_BUFFERS             = WGL_AUX_BUFFERS_ARB
};

enum EDrawSurfaceAcceleration
{
    E_NO_ACCELERATION      = WGL_NO_ACCELERATION_ARB,
    E_FULL_ACCELERATION    = WGL_FULL_ACCELERATION_ARB,    
    E_GENERIC_ACCELERATION = WGL_GENERIC_ACCELERATION_ARB
};

enum EDrawSurfaceSwapMethod
{
    E_SWAP_EXCHANGE  = WGL_SWAP_EXCHANGE_ARB,
    E_SWAP_COPY      = WGL_SWAP_COPY_ARB,
    E_SWAP_UNDEFINED = WGL_SWAP_UNDEFINED_ARB
};

enum EDrawSurfacePixelType
{
    E_TYPE_RGBA       = WGL_TYPE_RGBA_ARB,
    E_TYPE_COLORINDEX = WGL_TYPE_COLORINDEX_ARB
};

enum EPrimitiveType {
    E_PRIMITIVE_TYPE_POINTS         = GL_POINTS, 
    E_PRIMITIVE_TYPE_LINE_STRIP     = GL_LINE_STRIP, 
    E_PRIMITIVE_TYPE_LINE_LOOP      = GL_LINE_LOOP, 
    E_PRIMITIVE_TYPE_LINES          = GL_LINES, 
    E_PRIMITIVE_TYPE_TRIANGLE_STRIP = GL_TRIANGLE_STRIP, 
    E_PRIMITIVE_TYPE_TRIANGLE_FAN   = GL_TRIANGLE_FAN, 
    E_PRIMITIVE_TYPE_TRIANGLE_LIST  = GL_TRIANGLES
};

enum EIndexBufferType {
    E_IBUFFER_TYPE_UNSIGNED_BYTE = GL_UNSIGNED_BYTE,
    E_IBUFFER_TYPE_UNSIGNED_SHOR = GL_UNSIGNED_SHORT,
    E_IBUFFER_TYPE_UNSIGNED_INT  = GL_UNSIGNED_INT
};

enum EBufferTarget {
    E_VERTEX_BUFFER          = GL_ARRAY_BUFFER, 
    E_INDEX_BUFFER           = GL_ELEMENT_ARRAY_BUFFER,
    E_WRITE_PIXEL_TO_BUFFER  = GL_PIXEL_PACK_BUFFER,
    E_READ_PIXEL_FROM_BUFFER = GL_PIXEL_UNPACK_BUFFER
};

enum EBufferUsage {
    E_STREAM_DRAW  = GL_STREAM_DRAW, 
    E_STATIC_DRAW  = GL_STATIC_DRAW, 
    E_DYNAMIC_DRAW = GL_DYNAMIC_DRAW,
};

enum EBufferAccess {
    E_READ_ONLY = GL_READ_ONLY, 
    E_WRITE_ONLY = GL_WRITE_ONLY, 
    E_READ_WRITE = GL_READ_WRITE
};

enum ERenderTargetAttachment {
    E_RENDERTARGET_COLOR0 = 0,
    E_RENDERTARGET_COLOR1,
    E_RENDERTARGET_COLOR2,
    E_RENDERTARGET_COLOR3,
    E_RENDERTARGET_COLOR4,
    E_RENDERTARGET_COLOR5,
    E_RENDERTARGET_COLOR6,
    E_RENDERTARGET_COLOR7  
};

enum ECmpFunc {
    E_CMPFUNC_NEVER    = GL_NEVER,
    E_CMPFUNC_LESS     = GL_LESS,
    E_CMPFUNC_EQUAL    = GL_EQUAL,
    E_CMPFUNC_LEQUAL   = GL_LEQUAL,
    E_CMPFUNC_GREATER  = GL_GREATER,
    E_CMPFUNC_NOTEQUAL = GL_NOTEQUAL,
    E_CMPFUNC_GEQUAL   = GL_GEQUAL,
    E_CMPFUNC_ALWAYS   = GL_ALWAYS
};

enum EFaceType {
    E_FACE_FRONT     = GL_FRONT,
    E_FACE_BACK      = GL_BACK,
    E_FACE_FRONTBACK = GL_FRONT_AND_BACK
};

enum ECullFace {
    E_CULLFACE_CW  = GL_CW,
    E_CULLFACE_CCW = GL_CCW
};

enum EBlendOp {
    E_BLENDOP_ADD    = GL_FUNC_ADD,
    E_BLENDOP_SUB    = GL_FUNC_SUBTRACT,
    E_BLENDOP_REVSUB = GL_FUNC_REVERSE_SUBTRACT,
    E_BLENDOP_MIN    = GL_MIN,
    E_BLENDOP_MAX    = GL_MAX
};

enum EBlendFactor {
    E_BLENDFACTOR_ZERO                = GL_ZERO,
    E_BLENDFACTOR_ONE                 = GL_ONE,
    E_BLENDFACTOR_SRC_COLOR           = GL_SRC_COLOR,
    E_BLENDFACTOR_ONE_MINUS_SRC_COLOR = GL_ONE_MINUS_SRC_COLOR,
    E_BLENDFACTOR_SRC_ALPHA           = GL_SRC_ALPHA,
    E_BLENDFACTOR_ONE_MINUS_SRC_ALPHA = GL_ONE_MINUS_SRC_ALPHA,
    E_BLENDFACTOR_DST_ALPHA           = GL_DST_ALPHA,
    E_BLENDFACTOR_ONE_MINUS_DST_ALPHA = GL_ONE_MINUS_DST_ALPHA,
    E_BLENDFACTOR_DST_COLOR           = GL_DST_COLOR,
    E_BLENDFACTOR_ONE_MINUS_DST_COLOR = GL_ONE_MINUS_DST_COLOR,
};

enum EStencilOp {
    E_STENCILOP_KEEP      = GL_KEEP,
    E_STENCILOP_S_ZERO    = GL_ZERO,
    E_STENCILOP_REPLACE   = GL_REPLACE,
    E_STENCILOP_INCR      = GL_INCR,
    E_STENCILOP_DECR      = GL_DECR,
    E_STENCILOP_INVERT    = GL_INVERT,
    E_STENCILOP_INCR_WRAP = GL_INCR_WRAP,
    E_STENCILOP_DECR_WRAP = GL_DECR_WRAP
};

enum EPolygonMode {
    E_POLYGONMODE_POINT = GL_POINT,
    E_POLYGONMODE_LINE  = GL_LINE,
    E_POLYGONMODE_FILL  = GL_FILL       
};

enum EShaderType
{
    E_SHADERTYPE_VERTEX,
    E_SHADERTYPE_PIXEL
};

enum EShaderCodeType
{
    E_SHADERCODE_TYPE_SOURCE,
    E_SHADERCODE_TYPE_ENTRY,
    E_SHADERCODE_TYPE_COMPILEDSOURCE
};

enum EPassCodeType
{
    E_PASSCODE_SOURCE,
    E_PASSCODE_ENTRY,
    E_PASSCODE_COMPILEDSOURCE
};

enum EPassDomain
{
    E_PASSDOMAIN_VERTEX,
    E_PASSDOMAIN_GEOMETRY,
    E_PASSDOMAIN_PIXEL
};

enum EVertexEleType {
    E_VERTEXELETYPE_FLOAT = 0,
    E_VERTEXELETYPE_FLOAT2,
    E_VERTEXELETYPE_FLOAT3,
    E_VERTEXELETYPE_FLOAT4,
    
    E_VERTEXELETYPE_BYTE,
    E_VERTEXELETYPE_BYTE2,
    E_VERTEXELETYPE_BYTE3,
    E_VERTEXELETYPE_BYTE4,

    E_VERTEXELETYPE_UNSIGNED_BYTE,
    E_VERTEXELETYPE_UNSIGNED_BYTE2,
    E_VERTEXELETYPE_UNSIGNED_BYTE3,
    E_VERTEXELETYPE_UNSIGNED_BYTE4,

    E_VERTEXELETYPE_SHORT,
    E_VERTEXELETYPE_SHORT2,
    E_VERTEXELETYPE_SHORT3,
    E_VERTEXELETYPE_SHORT4,

    E_VERTEXELETYPE_UNSIGNED_SHORT,
    E_VERTEXELETYPE_UNSIGNED_SHORT2,
    E_VERTEXELETYPE_UNSIGNED_SHORT3,
    E_VERTEXELETYPE_UNSIGNED_SHORT4,

    E_VERTEXELETYPE_INT,
    E_VERTEXELETYPE_INT2,
    E_VERTEXELETYPE_INT3,
    E_VERTEXELETYPE_INT4,

    E_VERTEXELETYPE_UNSIGNED_INT,
    E_VERTEXELETYPE_UNSIGNED_INT2,
    E_VERTEXELETYPE_UNSIGNED_INT3,
    E_VERTEXELETYPE_UNSIGNED_INT4
};

enum ECoordWrap {
    E_WRAP_CLAMP           = GL_CLAMP,
    E_WRAP_CLAMP_EDGE      = GL_CLAMP_TO_EDGE,
    E_WRAP_CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER,
    E_WRAP_REPEAT          = GL_REPEAT,
    E_WRAP_MIRRORED_REPEAT = GL_MIRRORED_REPEAT
};

enum EMagFilter {
    E_MAG_NEAREST = GL_NEAREST,
    E_MAG_LINEAR  = GL_LINEAR
};

enum EMinFilter {
    E_MIN_NEAREST,
    E_MIN_LINEAR,
    E_MIN_ANISOTROPIC
};

enum EMipMapFilter {
    E_MIPMAP_NON,
    E_MIPMAP_NEAREST,
    E_MIPMAP_LINEAR,
};

enum ETexType {
    E_TEXTURE_2D       = GL_TEXTURE_2D,
    E_TEXTURE_3D       = GL_TEXTURE_3D,
    E_TEXTURE_CUBE_MAP = GL_TEXTURE_CUBE_MAP
};

enum EInterFormat {
    E_INTERFORMAT_ALPHA                      = GL_ALPHA,
    E_INTERFORMAT_ALPHA4                     = GL_ALPHA4,
    E_INTERFORMAT_ALPHA8                     = GL_ALPHA8,
    E_INTERFORMAT_ALPHA12                    = GL_ALPHA12,
    E_INTERFORMAT_ALPHA16                    = GL_ALPHA16,
    E_INTERFORMAT_LUMINANCE                  = GL_LUMINANCE,
    E_INTERFORMAT_LUMINANCE4                 = GL_LUMINANCE4,
    E_INTERFORMAT_LUMINANCE8                 = GL_LUMINANCE8,
    E_INTERFORMAT_LUMINANCE12                = GL_LUMINANCE12,
    E_INTERFORMAT_LUMINANCE16                = GL_LUMINANCE16,
    E_INTERFORMAT_LUMINANCE_ALPHA            = GL_LUMINANCE_ALPHA,
    E_INTERFORMAT_LUMINANCE4_ALPHA4          = GL_LUMINANCE4_ALPHA4,
    E_INTERFORMAT_LUMINANCE6_ALPHA2          = GL_LUMINANCE6_ALPHA2,
    E_INTERFORMAT_LUMINANCE8_ALPHA8          = GL_LUMINANCE8_ALPHA8,
    E_INTERFORMAT_LUMINANCE12_ALPHA4         = GL_LUMINANCE12_ALPHA4,
    E_INTERFORMAT_LUMINANCE12_ALPHA12        = GL_LUMINANCE12_ALPHA12,
    E_INTERFORMAT_LUMINANCE16_ALPHA16        = GL_LUMINANCE16_ALPHA16,
    E_INTERFORMAT_INTENSITY                  = GL_INTENSITY,
    E_INTERFORMAT_INTENSITY4                 = GL_INTENSITY4,
    E_INTERFORMAT_INTENSITY8                 = GL_INTENSITY8,
    E_INTERFORMAT_INTENSITY12                = GL_INTENSITY12,
    E_INTERFORMAT_INTENSITY16                = GL_INTENSITY16,
    E_INTERFORMAT_R3_G3_B2                   = GL_R3_G3_B2,
    E_INTERFORMAT_RGB                        = GL_RGB,
    E_INTERFORMAT_RGB4                       = GL_RGB4,
    E_INTERFORMAT_RGB5                       = GL_RGB5,
    E_INTERFORMAT_RGB8                       = GL_RGB8,
    E_INTERFORMAT_RGB10                      = GL_RGB10,
    E_INTERFORMAT_RGB12                      = GL_RGB12,
    E_INTERFORMAT_RGB16                      = GL_RGB16,
    E_INTERFORMAT_RGBA                       = GL_RGBA,
    E_INTERFORMAT_RGBA2                      = GL_RGBA2,
    E_INTERFORMAT_RGBA4                      = GL_RGBA4,
    E_INTERFORMAT_RGB5_A1                    = GL_RGB5_A1,
    E_INTERFORMAT_RGBA8                      = GL_RGBA8,
    E_INTERFORMAT_RGB10_A2                   = GL_RGB10_A2,
    E_INTERFORMAT_RGBA12                     = GL_RGBA12,
    E_INTERFORMAT_RGBA16                     = GL_RGBA16,
    E_INTERFORMAT_SLUMINANCE                 = GL_SLUMINANCE,
    E_INTERFORMAT_SLUMINANCE8                = GL_SLUMINANCE8,
    E_INTERFORMAT_SLUMINANCE_ALPHA           = GL_SLUMINANCE_ALPHA,
    E_INTERFORMAT_SLUMINANCE8_ALPHA8         = GL_SLUMINANCE8_ALPHA8,
    E_INTERFORMAT_SRGB                       = GL_SRGB,
    E_INTERFORMAT_SRGB8                      = GL_SRGB8,
    E_INTERFORMAT_SRGB_ALPHA                 = GL_SRGB_ALPHA,
    E_INTERFORMAT_SRGB8_ALPHA8               = GL_SRGB8_ALPHA8,

    E_INTERFORMAT_RGBA32F                    = GL_RGBA32F_ARB,
    E_INTERFORMAT_RGB32F                     = GL_RGB32F_ARB,
    E_INTERFORMAT_ALPHA32F                   = GL_ALPHA32F_ARB,
    E_INTERFORMAT_INTENSITY32F               = GL_INTENSITY32F_ARB,
    E_INTERFORMAT_LUMINANCE32F               = GL_LUMINANCE32F_ARB,
    E_INTERFORMAT_LUMINANCE_ALPHA32F         = GL_LUMINANCE_ALPHA32F_ARB,
    E_INTERFORMAT_RGBA16F                    = GL_RGBA16F_ARB,
    E_INTERFORMAT_RGB16F                     = GL_RGB16F_ARB,
    E_INTERFORMAT_ALPHA16F                   = GL_ALPHA16F_ARB,
    E_INTERFORMAT_INTENSITY16F               = GL_INTENSITY16F_ARB,
    E_INTERFORMAT_LUMINANCE16F               = GL_LUMINANCE16F_ARB,
    E_INTERFORMAT_LUMINANCE_ALPHA16F         = GL_LUMINANCE_ALPHA16F_ARB,

    E_INTERFORMAT_RGB_DXT1                   = GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
    E_INTERFORMAT_RGBA_DXT1                  = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
    E_INTERFORMAT_RGBA_DXT3                  = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
    E_INTERFORMAT_RGBA_DXT5                  = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,

    E_INTERFORMAT_NON
};

enum EDataFormat {
    E_DATAFORMAT_RED_UBYTE,
    E_DATAFORMAT_RED_BYTE,
    E_DATAFORMAT_RED_USHORT,
    E_DATAFORMAT_RED_SHORT,
    E_DATAFORMAT_RED_UINT,
    E_DATAFORMAT_RED_INT,
    E_DATAFORMAT_RED_FLOAT,

    E_DATAFORMAT_GREEN_UBYTE,
    E_DATAFORMAT_GREEN_BYTE,
    E_DATAFORMAT_GREEN_USHORT,
    E_DATAFORMAT_GREEN_SHORT,
    E_DATAFORMAT_GREEN_UINT,
    E_DATAFORMAT_GREEN_INT,
    E_DATAFORMAT_GREEN_FLOAT,

    E_DATAFORMAT_BLUE_UBYTE,
    E_DATAFORMAT_BLUE_BYTE,
    E_DATAFORMAT_BLUE_USHORT,
    E_DATAFORMAT_BLUE_SHORT,
    E_DATAFORMAT_BLUE_UINT,
    E_DATAFORMAT_BLUE_INT,
    E_DATAFORMAT_BLUE_FLOAT,

    E_DATAFORMAT_ALPHA_UBYTE,
    E_DATAFORMAT_ALPHA_BYTE,
    E_DATAFORMAT_ALPHA_USHORT,
    E_DATAFORMAT_ALPHA_SHORT,
    E_DATAFORMAT_ALPHA_UINT,
    E_DATAFORMAT_ALPHA_INT,
    E_DATAFORMAT_ALPHA_FLOAT,

    E_DATAFORMAT_LUMINANCE_UBYTE,
    E_DATAFORMAT_LUMINANCE_BYTE,
    E_DATAFORMAT_LUMINANCE_USHORT,
    E_DATAFORMAT_LUMINANCE_SHORT,
    E_DATAFORMAT_LUMINANCE_UINT,
    E_DATAFORMAT_LUMINANCE_INT,
    E_DATAFORMAT_LUMINANCE_FLOAT,

    E_DATAFORMAT_LUMINANCE_ALPHA_UBYTE,
    E_DATAFORMAT_LUMINANCE_ALPHA_BYTE,
    E_DATAFORMAT_LUMINANCE_ALPHA_USHORT,
    E_DATAFORMAT_LUMINANCE_ALPHA_SHORT,
    E_DATAFORMAT_LUMINANCE_ALPHA_UINT,
    E_DATAFORMAT_LUMINANCE_ALPHA_INT,
    E_DATAFORMAT_LUMINANCE_ALPHA_FLOAT,

    E_DATAFORMAT_RGB_UBYTE,
    E_DATAFORMAT_RGB_BYTE,
    E_DATAFORMAT_RGB_USHORT,
    E_DATAFORMAT_RGB_SHORT,
    E_DATAFORMAT_RGB_UINT,
    E_DATAFORMAT_RGB_INT,
    E_DATAFORMAT_RGB_FLOAT,

    E_DATAFORMAT_BGR_UBYTE,
    E_DATAFORMAT_BGR_BYTE,
    E_DATAFORMAT_BGR_USHORT,
    E_DATAFORMAT_BGR_SHORT,
    E_DATAFORMAT_BGR_UINT,
    E_DATAFORMAT_BGR_INT,
    E_DATAFORMAT_BGR_FLOAT,

    E_DATAFORMAT_RGBA_UBYTE,
    E_DATAFORMAT_RGBA_BYTE,
    E_DATAFORMAT_RGBA_USHORT,
    E_DATAFORMAT_RGBA_SHORT,
    E_DATAFORMAT_RGBA_UINT,
    E_DATAFORMAT_RGBA_INT,
    E_DATAFORMAT_RGBA_FLOAT,

    E_DATAFORMAT_BGRA_UBYTE,
    E_DATAFORMAT_BGRA_BYTE,
    E_DATAFORMAT_BGRA_USHORT,
    E_DATAFORMAT_BGRA_SHORT,
    E_DATAFORMAT_BGRA_UINT,
    E_DATAFORMAT_BGRA_INT,
    E_DATAFORMAT_BGRA_FLOAT,

    E_DATAFORMAT_RGB_UBYTE_3_3_2,
    E_DATAFORMAT_RGB_UBYTE_2_3_3_REV,
    E_DATAFORMAT_RGB_USHORT_5_6_5,
    E_DATAFORMAT_RGB_USHORT_5_6_5_REV,

    E_DATAFORMAT_BGR_UBYTE_3_3_2,
    E_DATAFORMAT_BGR_UBYTE_2_3_3_REV,
    E_DATAFORMAT_BGR_USHORT_5_6_5,
    E_DATAFORMAT_BGR_USHORT_5_6_5_REV,

    E_DATAFORMAT_RGBA_USHORT_4_4_4_4,
    E_DATAFORMAT_RGBA_USHORT_4_4_4_4_REV,
    E_DATAFORMAT_RGBA_USHORT_5_5_5_1,
    E_DATAFORMAT_RGBA_USHORT_1_5_5_5_REV,
    E_DATAFORMAT_RGBA_UINT_8_8_8_8,
    E_DATAFORMAT_RGBA_UINT_8_8_8_8_REV,
    E_DATAFORMAT_RGBA_UINT_10_10_10_2,
    E_DATAFORMAT_RGBA_UINT_2_10_10_10_REV,

    E_DATAFORMAT_BGRA_USHORT_4_4_4_4,
    E_DATAFORMAT_BGRA_USHORT_4_4_4_4_REV,
    E_DATAFORMAT_BGRA_USHORT_5_5_5_1,
    E_DATAFORMAT_BGRA_USHORT_1_5_5_5_REV,
    E_DATAFORMAT_BGRA_UINT_8_8_8_8,
    E_DATAFORMAT_BGRA_UINT_8_8_8_8_REV,
    E_DATAFORMAT_BGRA_UINT_10_10_10_2,
    E_DATAFORMAT_BGRA_UINT_2_10_10_10_REV,

    E_DATAFORMAT_RGB_DXT1,
    E_DATAFORMAT_RGBA_DXT1,
    E_DATAFORMAT_RGBA_DXT3,
    E_DATAFORMAT_RGBA_DXT5,

    E_DATAFORMAT_NON
};

enum ETexAccess {
    E_TEX_READ_ONLY = GL_READ_ONLY, 
    E_TEX_WRITE_ONLY = GL_WRITE_ONLY, 
    E_TEX_READ_WRITE = GL_READ_WRITE        
};

typedef struct SHParam
{
    friend class CShaderObject;
    friend class CFXObject;
public:
    SHParam( void ) : m_cgParam(NULL), m_iTexType(1), m_sName("") {}
    SHParam( const SHParam& l ) { (*this) = l; }        
    SHParam& operator= ( const SHParam& l ) { m_sName = l.m_sName; m_cgParam = l.m_cgParam; m_iTexType = l.m_iTexType; return (*this); }

    inline std::string getName( void ) { return m_sName; }
    inline bool isVaild( void ) const { return (m_cgParam ? true:false); }

protected:
    CGparameter m_cgParam;
    std::string m_sName;
    int m_iTexType;
}HSHADERPARAM;

struct SSemantic
{
public:
    SSemantic( const char* pSemantic, CGparameter cgParam ) : m_sSemantic(pSemantic), m_cgParam(cgParam), m_bEnable(false) {}

    std::string m_sSemantic;
    CGparameter m_cgParam;
    bool m_bEnable;
};

template<typename T> class CSingletonT
{
public:
    CSingletonT( void )
    {
        assert( !ms_Singleton );
            ms_Singleton = static_cast< T* >( this );
    }

    virtual ~CSingletonT( void )
    {  
        assert( ms_Singleton != NULL );  
        ms_Singleton = 0;  
    }

    static T& getSingleton( void )
    {       
        assert( ms_Singleton != NULL );  
        return ( *ms_Singleton ); 
    }

    static T* getSingletonPtr( void )
    { 
        return ms_Singleton; 
    }

private:
    CSingletonT(const CSingletonT<T> &);
    CSingletonT& operator=(const CSingletonT<T> &);

protected:
    static T* ms_Singleton;
};

template<typename T> T* CSingletonT<T>::ms_Singleton = NULL;

class IMutex
{
public:
    IMutex( void ) {}
    virtual void lock( void ) const = 0;
    virtual void unlock( void ) const = 0;

protected:
    IMutex( const IMutex& l );
    IMutex& operator=( const IMutex& l );
};

class CDefaultMutex : public IMutex
{
#ifdef WIN32
public:
    CDefaultMutex( void ) 
    {
        m_cs = new CRITICAL_SECTION; 
        if( m_cs ) 
            InitializeCriticalSection( m_cs ); 
    }

    virtual ~CDefaultMutex( void ) 
    {
        if( m_cs )
        {
            DeleteCriticalSection( m_cs );
            delete m_cs;
        }
    }

    virtual void lock( void ) const
    {
        if( m_cs )
           EnterCriticalSection( m_cs );
    }
    
    virtual void unlock( void ) const
    {
        if( m_cs )
            LeaveCriticalSection( m_cs );
    }

protected:
    CRITICAL_SECTION* m_cs;
#else // Other platform implementation:
public:
    PRS_API CDefaultMutex( void ) {}
    PRS_API virtual ~CDefaultMutex( void ) {}
    PRS_API virtual void lock( void ) const {}
    PRS_API virtual void unlock( void ) const {}

protected:
    void* m_cs;
#endif
};

class CMutexObject
{
public:
    CMutexObject( IMutex* pMutex )
    {
        m_pMutex = pMutex;
        m_pMutex->lock();
    }

    ~CMutexObject( void )
    {
        m_pMutex->unlock();
    }

protected:
    const IMutex* m_pMutex;
};


}//End namespace GL

}//End namespace Porman

#endif